import React from 'react'
import renderer from 'react-test-renderer'
import { mount } from 'enzyme'
import { ErrorModal } from 'components/ErrorModal'

const setup = (props = {}) => {
  const l10n = {
    formatMessage: error => error,
  }
  const newProps = {
    l10n,
    onClose: () => {},
    ...props,
  }

  const Component = <ErrorModal {...newProps} />
  const wrapper = mount(Component)

  return { Component, wrapper }
}

it('should render without errors', () => {
  const { wrapper } = setup()

  expect(wrapper).toBeTruthy()
})

it('should render right thing', () => {
  const { wrapper } = setup()

  expect(wrapper.state('show')).toBe(false)
})

it("should render right thing and don't change unexpected", () => {
  const { Component } = setup()
  const tree = renderer.create(Component).toJSON()

  expect(tree).toMatchSnapshot()
})

it('should display ErrorModal when setting `show` as true', () => {
  const { wrapper } = setup()

  wrapper.setState({ show: true })

  expect(wrapper.find('.modal.is-open').length).toBe(1)
})

it('should hide ErrorModal when clicking `Close` button', () => {
  const { wrapper } = setup()

  wrapper.setState({ show: true })
  expect(wrapper.state('show')).toBe(true)

  wrapper.find('button').simulate('click')
  expect(wrapper.state('show')).toBe(false)
})

it('should call `onClose` when closing ErrorModal', () => {
  const { wrapper } = setup()

  wrapper.find('button').simulate('click')
})

it('should have right lifecycle', () => {
  global.requestAnimationFrame = fn => fn()
  global.cancelAnimationFrame = jest.fn()

  const { wrapper } = setup()

  wrapper.instance().modal.box.addEventListener = (_, fn) => fn()
  expect(wrapper.state().show).toBe(true)

  wrapper.find('button').simulate('click')
  expect(wrapper.state().show).toBe(false)

  wrapper.unmount()
  expect(global.cancelAnimationFrame).toBeCalled()
})

it('should use error text instead of localized message if `l10n.formatMessage` return null', () => {
  const { wrapper } = setup({
    l10n: {
      formatMessage: () => null,
    },
  })

  expect(wrapper).toBeTruthy()
})
